package cn.itwen.star.graph.core.service.impl;
import cn.itwen.star.graph.core.mapper.UserFundMapper;
import cn.itwen.star.graph.core.mapper.UserFundRecordMapper;
import cn.itwen.star.graph.core.pojo.User;
import cn.itwen.star.graph.core.pojo.UserFund;
import cn.itwen.star.graph.core.pojo.UserFundRecord;
import cn.itwen.star.graph.core.service.UserFundRecordService;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
* <p>
* sg_user_fund_record Service 接口实现
* </p>
*
* @author luoxu
* @since 2024-08-27 11:11:49
*/
@Service
@Transactional
@Slf4j
public class UserFundRecordServiceImpl extends ServiceImpl<UserFundRecordMapper, UserFundRecord> implements UserFundRecordService {

    @Autowired
    private UserFundMapper userFundMapper;

    /**
     * 积分冻结：指从用户积分账户拿出积分，增加到用户积分冻结账户上
     * @param userId
     * @param money
     */
    @Override
    public void pointsFreeze(Long userId, Integer money) {
        UserFund userFund = getUserFund(userId);
        if(userFund.getScore()>=money){
            userFund.setScore(userFund.getScore()-money);
            userFund.setFreezeScore(userFund.getFreezeScore()+money);
            userFundMapper.updateById(userFund);
            addFundRecord(userFund.getId(),-money,0);
            addFundRecord(userFund.getId(),money,1);
        }else{
            throw new RuntimeException("账户积分不足");
        }
    }

    /**
     * 冻结归还：指从积分冻结账户上拿出积分，增加到用户积分账户上
     * @param userId
     * @param money
     */
    @Override
    public void freezeReturn(Long userId, Integer money) {
        UserFund userFund = getUserFund(userId);
        if(userFund.getFreezeScore()>=money){
            userFund.setScore(userFund.getScore()+money);
            userFund.setFreezeScore(userFund.getFreezeScore()-money);
            userFundMapper.updateById(userFund);
            addFundRecord(userFund.getId(),money,0);
            addFundRecord(userFund.getId(),-money,1);
        }else{
            throw new RuntimeException("冻结账户积分不足");
        }
    }

    /**
     * 积分扣除：指从用户积分冻结账号上拿出积分，增加到总账户的积分账户上
     * @param userId
     * @param money
     */
    @Override
    public void pointsDeduction(Long userId, Integer money) {
        UserFund userFund = getUserFund(userId);
        if(userFund.getFreezeScore()>=money){
            userFund.setFreezeScore(userFund.getFreezeScore()-money);
            userFundMapper.updateById(userFund);
            UserFund allFund = getUserFund(0L);
            allFund.setScore(allFund.getScore()+money);
            userFundMapper.updateById(allFund);
            addFundRecord(userFund.getId(),-money,1);
            addFundRecord(allFund.getId(),money,0);
        }else{
            throw new RuntimeException("冻结账户积分不足");
        }
    }

    /**
     * 直接划扣：指从用户的积分账户上拿出积分，增加到总账户的积分账户上
     * @param userId
     * @param money
     */
    @Override
    public void directDeduction(Long userId, Integer money) {
        UserFund userFund = getUserFund(userId);
        if(userFund.getScore()>=money){
            userFund.setFreezeScore(userFund.getScore()-money);
            userFundMapper.updateById(userFund);
            UserFund allFund = getUserFund(0L);
            allFund.setScore(allFund.getScore()+money);
            userFundMapper.updateById(allFund);
            addFundRecord(userFund.getId(),-money,0);
            addFundRecord(allFund.getId(),money,0);
        }else{
            throw new RuntimeException("账户积分不足");
        }
    }

    /**
     * 积分fanhhuan
     * @param user
     * @param i
     */
    @Override
    public UserFundRecord deductionReturnScore(User user, int i) {
        UserFund userFund = getUserFund(user.getId());
        UserFundRecord userFundRecord = addFundRecord(userFund.getId(),i,1);
        userFund.setScore(userFund.getScore()+ i);
        try {
            userFundMapper.updateById(userFund);
        }catch (Exception e){
            e.printStackTrace();
            throw new RuntimeException("积分扣除失败");
        }
        return userFundRecord;
    }

    /**
     * 获取一个用户的账户，如果没有则创建一个
     * @param userId
     * @return
     */
    private UserFund getUserFund(Long userId) {
        UserFund userFund = userFundMapper.selectOne(Wrappers.<UserFund>lambdaQuery().eq(UserFund::getUserId, userId));
        if(userFund==null){
            userFund = new UserFund();
            userFund.setUserId(userId);
            userFund.setVersion(1L);
            userFund.setScore(0L);
            userFund.setFreezeScore(0L);
            userFundMapper.insert(userFund);
        }
        return userFund;
    }


    /**
     * 插入一条流水信息
     *
     * @param fundId
     * @param money
     * @param fundType
     * @return
     */
    private UserFundRecord addFundRecord(Long fundId, Integer money, Integer fundType) {
        UserFundRecord userFundRecord = new UserFundRecord();
        userFundRecord.setMoney(money);
        userFundRecord.setFundType(fundType);
        userFundRecord.setFundId(fundId);
        this.save(userFundRecord);
        return userFundRecord;
    }


}